<template>
  <div class="dishes-page">
    <el-row justify="space-between" align="middle">
      <h2>菜品中心 · {{ storeName }}</h2>
      <el-button type="primary" @click="openAddDialog">新增菜品</el-button>
    </el-row>

    <!-- 搜索 -->
    <el-row class="mb" :gutter="12">
      <el-col :span="6">
        <el-input
          v-model="keyword"
          placeholder="菜品名称"
          clearable
          @clear="load"
        />
      </el-col>
      <el-col :span="4">
        <el-button @click="load">搜索</el-button>
      </el-col>
    </el-row>

    <!-- 分类折叠面板 -->
    <el-collapse>
      <el-collapse-item
        v-for="g in groupedList"
        :key="g.category.id"
        :title="`${g.category.name}（${g.dishes.length}）`"
      >
        <el-empty
          v-if="!g.dishes.length"
          description="暂无菜品"
          :image-size="40"
        />
        <el-table v-else :data="g.dishes" stripe>
          <el-table-column prop="id" label="ID" width="80" />
          <el-table-column prop="name" label="菜品名称" />
          <el-table-column prop="price" label="单价" width="100">
            <template #default="s">¥{{ s.row.price.toFixed(2) }}</template>
          </el-table-column>
          <el-table-column prop="stock" label="库存" width="100" />
        <el-table-column label="图片" width="120">
            <template #default="s">
              <img
                v-if="s.row.imageUrl"
                :src="s.row.imageUrl"
                class="mini-img"
              />
              <span v-else>无图</span>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="180">
            <template #default="s">
              <el-button size="small" @click="openEditDialog(s.row)">
                编辑
              </el-button>
              <el-button size="small" type="danger" @click="del(s.row.id)">
                删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-collapse-item>
    </el-collapse>

    <!-- 新增/编辑弹窗 -->
    <el-dialog
      v-model="dialog"
      :title="isEdit ? '编辑菜品' : '新增菜品'"
      width="420"
    >
      <el-form :model="form" label-width="80">
        <el-form-item label="名称">
          <el-input v-model="form.name" />
        </el-form-item>

        <!-- 分类下拉框 -->
        <el-form-item label="分类">
          <el-select v-model="form.categoryId" clearable filterable>
            <el-option
              v-for="c in categoryOptions"
              :key="c.id"
              :label="c.name"
              :value="c.id"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="单价">
          <el-input-number
            v-model="form.price"
            :precision="2"
            :min="0"
          />
        </el-form-item>
        <el-form-item label="库存">
          <el-input-number v-model="form.stock" :min="0" />
        </el-form-item>
        <el-form-item label="图片">
  <el-upload
    class="avatar-uploader"
    action="/api/upload/image"
    :show-file-list="false"
    :on-success="handleUploadSuccess"
    :before-upload="beforeUpload"
    :headers="{ Authorization: 'Bearer ' + useAuthStore().token }"
    name="file"
  >
    <img v-if="form.imageUrl" :src="form.imageUrl" class="avatar" />
    <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
  </el-upload>
</el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialog = false">取消</el-button>
        <el-button type="primary" @click="submit">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import axios from '@/api/request'
import { useAuthStore } from '@/stores/auth'
import { jwtDecode } from 'jwt-decode'

/* ---------- 类型定义 ---------- */
interface Dish {
  id?: number
  name: string
  price: number
  stock: number
  imageUrl?: string
  categoryId: number
}

interface Category {
  id: number
  name: string
}

interface GroupItem {
  category: Category
  dishes: Dish[]
}

interface JwtPayload {
  storeId: number
  storeName: string
}

/* ---------- 登录信息 ---------- */
const auth = useAuthStore()
const payload = computed<JwtPayload>(() =>
  auth.token
    ? (jwtDecode<JwtPayload>(auth.token) as JwtPayload)
    : ({ storeId: 0, storeName: '未知门店' } as JwtPayload)
)

const storeId = computed<number>(() => payload.value.storeId)
const storeName = computed<string>(() => payload.value.storeName)

/* ---------- 响应式数据 ---------- */
const list = ref<Dish[]>([])
const keyword = ref('')
const dialog = ref(false)
const isEdit = ref(false)
const form = ref<Dish>({
  name: '',
  price: 0,
  stock: 0,
  imageUrl: '',
  categoryId: 0
})

const categoryOptions = ref<Category[]>([])

/* ---------- 按分类分组 ---------- */
const groupedList = computed<GroupItem[]>(() => {
  const map: Record<number, Dish[]> = {}
  list.value.forEach(d => {
    const cid = d.categoryId
    if (!map[cid]) map[cid] = []
    map[cid].push(d)
  })
  // 按 categoryOptions 的顺序返回，保证分类顺序固定
  return categoryOptions.value.map(c => ({
    category: c,
    dishes: map[c.id] || []
  }))
})
/* ---------- 上传图片 ---------- */
const handleUploadSuccess = (res: any) => {
  if (res.code === 200) {
    form.value.imageUrl = `http://localhost:8080${res.data}`
    ElMessage.success('上传成功')
  } else {
    ElMessage.error(res.message || '上传失败')
  }
}

const beforeUpload = (file: File) => {
  const isImage = file.type.startsWith('image/')
  const isLt5M = file.size / 1024 / 1024 < 5

  if (!isImage) {
    ElMessage.error('只能上传图片')
  }
  if (!isLt5M) {
    ElMessage.error('图片大小不能超过 5MB')
  }
  return isImage && isLt5M
}

/* ---------- 业务方法 ---------- */
const load = () =>
  axios
    .get('/dish/search', { params: { name: keyword.value, storeId: storeId.value } })
    .then(res => {
      list.value = res.data.map((d: Dish) => ({
        ...d,
        imageUrl: d.imageUrl && !d.imageUrl.startsWith('http')
          ? `http://localhost:8080${d.imageUrl}`
          : d.imageUrl
      }))
    })

const loadCategories = () =>
  axios
    .get('/category', { params: { storeId: storeId.value } })
    .then(res => (categoryOptions.value = res.data))

const openAddDialog = () => {
  isEdit.value = false
  form.value = { name: '', price: 0, stock: 0, imageUrl: '', categoryId: 0 }
  dialog.value = true
}

const openEditDialog = (row: Dish) => {
  isEdit.value = true
  form.value = { ...row }
  dialog.value = true
}

const submit = () => {
  if (!form.value.name) {
    ElMessage.warning('请输入菜品名称')
    return
  }
  if (!form.value.categoryId) {
    ElMessage.warning('请选择分类')
    return
  }

  const api = isEdit.value
    ? axios.put('/dish', { ...form.value }, { params: { storeId: storeId.value } })
    : axios.post('/dish', { ...form.value }, { params: { storeId: storeId.value } })

  api
    .then(() => {
      dialog.value = false
      load()
      ElMessage.success(isEdit.value ? '已更新' : '已添加')
    })
}

const del = (id: number) =>
  ElMessageBox.confirm('确定删除？').then(() =>
    axios.delete('/dish/batch', {
      params: { storeId: storeId.value },
      data: [id]
    })
  ).then(() => {
    ElMessage.success('已删除')
    load()
  })

/* ---------- 初始化 ---------- */
onMounted(() => {
  load()
  loadCategories()
})
</script>

<style scoped>
.mini-img {
  width: 60px;
  height: 40px;
  object-fit: cover;
  border-radius: 4px;
}
.dishes-page {
  padding: 16px;
}
.mb {
  margin-bottom: 12px;
}
</style>